/**
 * Copyright (c) 2023 murenchao
 * taomu is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *       http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package cool.taomu.box.guice.util

import com.google.common.collect.ArrayListMultimap
import java.io.File
import java.io.FileInputStream
import java.util.List
import java.util.Map
import java.util.Properties
import java.util.UUID
import org.apache.commons.io.FileUtils
import org.apache.commons.lang3.StringUtils
import org.yaml.snakeyaml.Yaml

class PropertyUtils {
	def static load(String prefix) {
		return load(prefix, PropertyUtils.getClass());
	}

	def static load(String prefix, Class<?> zlass) {
		if (prefix.endsWith(".yml")) {
			var fpath = ymlToProperty(prefix)
			var pro = new Properties();
			try(var in = new FileInputStream(fpath)) {
				pro.load(in);
				fpath.delete
			}
			return pro;
		} else {
			var pro = new Properties();
			// var in = zlass.getResource("/" + prefix).openStream;
			try(var in =  TaomuResource.read(prefix)) {
				pro.load(in);
			}
			return pro;
		}

	}

	def static ymlToProperty(String prefix) {
		val m = ArrayListMultimap.create();
		var yml = new Yaml()
		var results = yml.loadAs(TaomuResource.read(prefix), Map)
		results.forEach [ k, v |
			if (v instanceof Map) {
				toProperty(m, k, v)
			} else if (v instanceof List) {
				v.forEach [
					toProperty(m, k, it)
				]
			} else {
				m.put(k, v);
			}
		]
		val pfile = File.createTempFile(UUID.randomUUID.toString, ".properties");
		m.forEach([ k, v |
			FileUtils.writeStringToFile(pfile, #[k, v].join("=") + "\n", "UTF-8", true);
		])
		return pfile;
	}

	private static def void toProperty(ArrayListMultimap<String, Object> convert, String key, Map<String, Object> map) {
		map.forEach [ k, v |
			val String namespace = StringUtils.isNotBlank(key) ? #[key, k].join(".") : k
			if (v instanceof Map) {
				toProperty(convert, namespace, v);
			} else if (v instanceof List) {
				v.forEach [
					toProperty(convert, namespace, it)
				]
			} else {
				convert.put(namespace, v);
			}
		]
	}
}
